Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WebView] Support saving and loading state and custom layout params #1557

Merged
merged 5 commits into from
Apr 14, 2023

Conversation

bentrengrove
Copy link
Collaborator

@bentrengrove bentrengrove commented Mar 24, 2023

Enables the ability to save and restore WebView state when leaving and reentering composition.

In order to restore state you must use the new rememberSaveableWebViewState() API that doesn't take an initial URL.
Then you can check if any view state exists before loading a URL in the WebView. This also allows for state to not be restored if required.

val webViewState = rememberSaveableWebViewState()
    val navigator = rememberWebViewNavigator()

    LaunchedEffect(navigator) {
        val bundle = webViewState.viewState
        if (bundle == null) {
            // This is the first time load, so load the home page.
            navigator.loadUrl("https://bbc.com")
        }
    }

    WebView(
        state = webViewState,
        navigator = navigator,
        modifier = Modifier.fillMaxSize()
    )

As part of this refactor, a new API was introduced that allows custom LayoutParams to be passed into the WebView composable. There are now two entry points, one that attempts to size itself based on Modifier constraints and one where you must pass in the appropriate LayoutParams to size the WebView correctly.

Fixes #1178
Fixes #1407
Fixes #1435
Fixes #1563
Fixes #1573
Fixes #1564

@bentrengrove bentrengrove changed the base branch from ben/webview_reusable to main March 28, 2023 06:23
@bentrengrove bentrengrove force-pushed the ben/webview_savestate branch from 352141a to a6b9f87 Compare April 4, 2023 05:56
@bentrengrove bentrengrove changed the title [WebView] WIP Support saving and loading state [WebView] Support saving and loading state and custom layout params Apr 4, 2023
@bentrengrove bentrengrove marked this pull request as ready for review April 13, 2023 03:59
Copy link
Collaborator

@alexvanyo alexvanyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@bentrengrove bentrengrove merged commit b6c1870 into main Apr 14, 2023
@bentrengrove bentrengrove deleted the ben/webview_savestate branch April 14, 2023 21:38
@bentrengrove
Copy link
Collaborator Author

It will be in the next release in approximately two weeks time

@bentrengrove
Copy link
Collaborator Author

This has just been released to maven in 0.31.1-alpha

@R4M5E5
Copy link

R4M5E5 commented Jun 6, 2023

Is it somehow possible to hoist the webViewState and the navigator above the NavHost? So for example in the WebViewSaveStateSample.kt to call the rememberSaveableWebViewState() and the rememberWebViewNavigator() just right after the rememberNavController() call and then pass down the webViewState and the navigator to the Home composable via arguments?

So something like:

val navController = rememberNavController()
val webViewState = rememberSaveableWebViewState()
val navigator = rememberWebViewNavigator()

LaunchedEffect(navigator) {
   val bundle = webViewState.viewState
   if (bundle == null) {
      // This is the first time load, so load the home page.
      navigator.loadUrl("https://bbc.com")
   }
}


NavHost(navController = navController, startDestination = "home") {
   composable("home") {
      Home(webViewState, navigator)
    }
   composable("detail") {
       Detail()
    }
}                   

Because for me this doesn't work. With this approach the webview is not keeping the state after navigating. Any idea how to make this work?

@rafakob
Copy link

rafakob commented Jul 3, 2023

Is there a way to remember WebView state which is in a LazyColumn item? I'm testing the rememberSaveableWebViewState but when I scroll away from that item and go back to it - WebView refreshes the page.

@YugeCse
Copy link

YugeCse commented Jul 28, 2023

I put a webview into a ScrollableControlView, Then I click one button, and the page navigates to annother page. Then, I back to the webview page, the webview refreshes the page. It loss its scroll position.

Box(Modifier.fillMaxSize().verticalScroll(rememberScrollState())){
Button(Modifier.click(gotoAnnotherPage)){ Text('NEXT PAGE') }
WebView(Modifier.fillMaxWidth().wrapContentHeight())
Text('Hello , this is a test!')
}

Is there any way to remember the scroll position? Thank you!

@nickboris
Copy link

Thank you @bentrengrove for adding this functionality, I think it's a great step in making webviews easier to manage with compose. I wanted to second the use case that @rafakob mentioned above. I have a small webview element being displayed in a lazy column that I can't revert to a non-recycling column due to performance concerns, and the reloads are quite jarring from a UX perspective. Will be following this thread to see if there are any updates/plans to help support this use case in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment